package interrupt;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;

@Slf4j
public class InterruptTask implements  Runnable {

    private LinkedBlockingQueue<Object> blockingQueue = new LinkedBlockingQueue<>(100);

    // 这个写法作为while里的循环控制变量
    private AtomicBoolean running = new AtomicBoolean(true);

    public void submit(Object task) throws InterruptedException {
        blockingQueue.put(task);
    }

    @Override
    public void run() {
        while(running.get()) {
            Object task = null;
            try {
                // take内部会触发lock，AbstractQueuedSynchronizer #1642行附近 抛异常
                task = blockingQueue.take();
                log.info("this moment, take task:{}", task);
                doSome1(task);

                doTimeCostSome2(task);
            } catch (InterruptedException e) {
                log.info("running thread was interrupted, {}", e);
                // 重新设置中断状态
                Thread.currentThread().interrupt();
            }
            if (Thread.currentThread().isInterrupted()) {
                log.info(">>>thread was interrupted!");
                break;
            }
        }
    }

    private void doSome1(Object task) {
        log.info("doSome1...");
       // sleepSome(50L);
    }

    private void doTimeCostSome2(Object task) {
        log.info("doTimeCostSome2...");
      //  sleepSome(5*1000L);
    }

    private void sleepSome(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) throws Exception {
        InterruptTask interruptTask = new InterruptTask();
        interruptTask.submit("task1");
        interruptTask.submit("task2");

        Thread t1 = new Thread(interruptTask);
        t1.start();
        interruptTask.submit("task3");
        Thread.sleep(3000L);
        log.info("try to interrupt t1 thread...");
        // 如果t1线程此刻之前被sleep, wait,lock，会被中断抛异常，中断位自动清掉
        // 仅仅interrupt()只是打了一个中断标识
        t1.interrupt();
        t1.join();
    }
}
